using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Qreed.Windows.Forms
{
    /// <summary>
    /// Tool class to assign the global system imagelist to a control.
    /// </summary>
    public static class SystemImageList
    {
        private static IntPtr _imgHandle = IntPtr.Zero;
        private const UInt32 TVSIL_NORMAL = 0;
        private const UInt32 TVM_SETIMAGELIST = 4361;
        private const int LVM_FIRST = 0x1000;
        private const int LVM_SETIMAGELIST = (LVM_FIRST + 3);
        private const int LVSIL_NORMAL = 1;
        private const int LVSIL_SMALL = 1;

        /// <summary>
        /// Initializes the <see cref="SystemImageList"/> class.
        /// </summary>
        static SystemImageList()
        {
            Shell32.SHFILEINFO fileInfo = new Shell32.SHFILEINFO();
            Shell32.SHGFI flags = Shell32.SHGFI.SHGFI_USEFILEATTRIBUTES |
                                  Shell32.SHGFI.SHGFI_SMALLICON |
                                  Shell32.SHGFI.SHGFI_SYSICONINDEX;

            _imgHandle = Shell32.SHGetFileInfo(".bleeh", Shell32.FILE_ATTRIBUTE_NORMAL, 
                                               out fileInfo, (uint)Marshal.SizeOf(fileInfo), flags);

            if (_imgHandle == IntPtr.Zero)
                throw (new ApplicationException("Failed to locate system imagelist."));
        }

        /// <summary>
        /// Assigns the image list to a treeview.
        /// </summary>
        /// <param name="treeView">The treeview.</param>
        public static void AssignToTreeView(TreeView treeView)
        {
            AssignToTreeView(treeView.Handle);
        }

        /// <summary>
        /// Assigns the image list to a treeview.
        /// </summary>
        /// <param name="hWnd">The window handle of the treeview.</param>
        public static void AssignToTreeView(IntPtr hWnd)
        {
            int res = User32.SendMessage(hWnd, TVM_SETIMAGELIST, TVSIL_NORMAL, (uint)_imgHandle);
            if (res!= 0)
                Marshal.ThrowExceptionForHR(res);
        }

        /// <summary>
        /// Assigns the image list to a listview.
        /// </summary>
        /// <param name="listView">The list view.</param>
        public static void AssignToListView(ListView listView)
        {
            AssignToListView(listView.Handle);
        }

        /// <summary>
        /// Assigns the image list to a listview.
        /// </summary>
        /// <param name="hWnd">The window handle of the listview.</param>
        public static void AssignToListView(IntPtr hWnd)
        {
            int res = User32.SendMessage(hWnd, LVM_SETIMAGELIST, LVSIL_SMALL, (uint)_imgHandle);
            if (res != 0)
                Marshal.ThrowExceptionForHR(res);
        }
    }
}
